package br.com.klis.batendoumabola.server;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;

import br.com.klis.batendoumabola.client.service.ImagemDoBateBolaService;
import br.com.klis.batendoumabola.server.model.ImagemDoBateBola;
import br.com.klis.batendoumabola.server.util.DadosDaImagemServerUtil;
import br.com.klis.batendoumabola.server.util.ImageUtil;
import br.com.klis.batendoumabola.shared.DadosDaImagem;

import com.google.appengine.api.datastore.Blob;
import com.google.appengine.api.images.Image;
import com.google.appengine.api.images.ImagesServiceFactory;
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyService;


@SuppressWarnings("serial")
public class UploadBlobServlet extends HttpServlet {
    //private static final Logger log = Logger.getLogger(UploadServlet.class.getName());
	
	public void doPost(HttpServletRequest req, HttpServletResponse res)throws ServletException, IOException {
		PrintWriter resp = res.getWriter();
		try {
			/*int len = req.getContentLength();
	    	int mb = (1024 * 1024) * 1;
	    	if (len > mb) {
	    		throw new RuntimeException("Sorry that file is to large. Try < 1024 or 1MB file");  
	    	}*/
			
			System.out.println("Upload Content Type: "+req.getContentType());
			
			ServletFileUpload upload = new ServletFileUpload();
			//upload.setSizeMax(1048576); //1024 * 1024 
			upload.setSizeMax(2097152);  //1024 * 1024 * 2
			res.setContentType("text/plain");
			
			
			ImagemDoBateBola img = new ImagemDoBateBola();
			DadosDaImagem dados = new DadosDaImagem();
			
			String bateBolaId = null;
			try {
				FileItemIterator iterator = upload.getItemIterator(req);
				while (iterator.hasNext()) {
					FileItemStream item = iterator.next();
					InputStream in = item.openStream();
					if (item.isFormField()) {
						try{
							bateBolaId = IOUtils.toString(in);
							img.setBateBolaId(new Long(bateBolaId));
							dados.setBateBolaId(new Long(bateBolaId));
						}finally{
							IOUtils.closeQuietly(in);
						}
					} else {
						String fileName = item.getName();
						img.setFieldName(item.getFieldName());
						dados.setFieldName(item.getFieldName());
						String contentType = item.getContentType();
						img.setContentType(contentType);
						dados.setContentType(contentType);
						img.setFileName(fileName);
						dados.setFileName(fileName);
						img.setCreation(new Date());
						dados.setCreation(new Date());
						
						byte[] fileContents = null;
						try {
							fileContents = IOUtils.toByteArray(in);
							Image image = ImagesServiceFactory.makeImage(fileContents);
	    	    			img.setWidth(image.getWidth());
	    	    			dados.setWidth(image.getWidth());
	    	    			img.setHeight(image.getHeight());
	    	    			dados.setHeight(image.getHeight());
							img.setSize(fileContents.length);
							dados.setSize(fileContents.length);
							img.setConteudo(new Blob(fileContents));
							dados.setConteudo(fileContents);
						} finally {
							IOUtils.closeQuietly(in);
						}
					}
				}
				
				ImagemDoBateBolaService servico = new ImagemDoBateBolaServiceImpl();
				dados = servico.save(dados);
				
				String retorno = DadosDaImagemServerUtil.generateString(dados);
				System.out.println(retorno);
				resp.write(retorno);
				resp.flush();
			} catch (SizeLimitExceededException e) {
				resp.write("Erro: O tamanho máximo de "+ e.getPermittedSize() + " bytes foi excedido. Tamanho do arquivo: "+ e.getActualSize() + " bytes.");
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			resp.write("Erro: "+ex.getMessage());
		}
	}
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
    		throws ServletException, IOException {
    	
    	String idDaImagem;
    	String texto = req.getParameter("texto");
    	String imageId = req.getParameter("imageId");
    	if (texto == null || texto.equals("")){
        	if (imageId == null || imageId.equals("")){
        		return;
        	}else{
        		idDaImagem = imageId;
        	}
    	}else{
    		idDaImagem = texto;
    	}
    	
    	String tipo = req.getParameter("tipo");
    	String width = req.getParameter("width");
    	String height = req.getParameter("height");
    	
    	String widthDefault = "60";
    	String heightDefault = "60";
    	 
    	Objectify ofy = ObjectifyService.begin();
    	ImagemDoBateBola imagemDoBateBola = ofy.find(ImagemDoBateBola.class, new Long(idDaImagem));
    	if (imagemDoBateBola != null){
    		if(imagemDoBateBola.getConteudo() != null){
    			if(tipo!=null){
    				byte[] newImageData;
    				if(tipo.equals("thumb")){
    					if(imagemDoBateBola.getThumb() != null){
        					resp.getOutputStream().write(imagemDoBateBola.getThumb().getBytes());	
        				}else{
        					newImageData = ImageUtil.resizeImage(imagemDoBateBola.getConteudo().getBytes(), 60, 60);
        	                resp.getOutputStream().write(newImageData);
        				}
    				}else if (tipo.equals("custom")){
    					if (width == null || width.equals("") || !StringUtils.isNumeric(width)){
    			    		width = widthDefault;
    			    	}
    			    	if (height == null || height.equals("") || !StringUtils.isNumeric(height)){
    			    		height = heightDefault;
    			    	}
    					newImageData = ImageUtil.resizeImage(imagemDoBateBola.getConteudo().getBytes(), new Integer(width), new Integer(height));
    					resp.getOutputStream().write(newImageData);
    				}
    			}else{
    				resp.getOutputStream().write(imagemDoBateBola.getConteudo().getBytes());	
    			}
    			resp.getOutputStream().flush();
        	}
    	}
    }
}
